package com.zzr.demo.redis.service.impl;

import com.zzr.demo.redis.service.LocationDisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: xiaomi
 * @date: 2021/10/11
 * @description:
 */
@Service
@Slf4j
public class LocationDisServiceImpl implements LocationDisService {

    final String GEO_LOC_DIST_KEY = "geo::loc::dist";
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public void addLoc(double longitude, double latitude, String name) {
        GeoOperations<String, String> opsForGeo = stringRedisTemplate.opsForGeo();
        Long add = opsForGeo.add(GEO_LOC_DIST_KEY, new Point(longitude, latitude), name);
        log.info("add {},{},{},return {}", longitude, latitude, name, add);

    }

    @Override
    public String getLoc(String name) {
        GeoOperations<String, String> opsForGeo = stringRedisTemplate.opsForGeo();
        List<Point> position = opsForGeo.position(GEO_LOC_DIST_KEY, name);
        if (position.size() > 0) {
            log.info("{} position:{}", name, position.get(0));
            return position.get(0).getX() + "," + position.get(0).getY();
        }
        return null;
    }

    @Override
    public double calLoc(String name1, String name2) {
        GeoOperations<String, String> opsForGeo = stringRedisTemplate.opsForGeo();
        //GEODIST key loc1 loc2 unit=km
        Distance distance = opsForGeo.distance(GEO_LOC_DIST_KEY, name1, name2, RedisGeoCommands.DistanceUnit.KILOMETERS);
        log.info("{},{} 的距离为：{} {}", distance.getValue(), distance.getUnit());
        return distance.getValue();
    }

    /**
     * 可以返回距离和坐标
     *
     * @param name
     * @param kms  km 数
     * @return
     */
    @Override
    public List<String> nearby(String name, int kms) {
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeCoordinates().includeDistance();
        GeoOperations<String, String> opsForGeo = stringRedisTemplate.opsForGeo();
        GeoResults<RedisGeoCommands.GeoLocation<String>> radius = opsForGeo.radius(GEO_LOC_DIST_KEY, name, new Distance(kms, RedisGeoCommands.DistanceUnit.KILOMETERS), geoRadiusCommandArgs);

        List<String> list = new ArrayList<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> item : radius) {
            RedisGeoCommands.GeoLocation<String> content = item.getContent();
            Distance distance = item.getDistance();
            log.info("content:{},distance:{}", content, distance);
            list.add(content.toString());
        }
        return list;
    }
}
